﻿using Ledict.ConditionExtract.Common;
using Ledict.ConditionExtract.Model;
using MySql.Data.MySqlClient;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.SqlClient;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using static Ledict.ConditionExtract.Frm.FrmLogin;

namespace Ledict.ConditionExtract.Frm
{
    /// <summary>
    /// 信息单元比对
    /// </summary>
    public partial class RegexManage : Form
    {
        /// <summary>
        /// 当前数据库信息
        /// </summary>
        public DataBaseSave CurrentDataBaseInfo { get; set; } = new DataBaseSave() { DataBaseInfos=new List<DataBaseInfo>() };

        /// <summary>
        /// 来源数据库信息集合
        /// </summary>
        private List<DataBaseInfo> sourceDataBases=new List<DataBaseInfo>();

        /// <summary>
        /// 目标数据库信息集合
        /// </summary>
        private List<DataBaseInfo> targetDataBases = new List<DataBaseInfo>();

        /// <summary>
        /// sqlServer数据库信息集合
        /// </summary>
        private List<DataBaseInfo> sqlServerDataBases = new List<DataBaseInfo>();

        /// <summary>
        /// mySql数据库信息集合
        /// </summary>
        private List<DataBaseInfo> mySqlDataBases = new List<DataBaseInfo>();

        public RegexManage()
        {
            InitializeComponent();
            //默认选择2.0
            try
            {
                cmbRegexType.SelectedIndex = 1;
                if (FrmLogin.configInfo.DataBaseInfo != null)
                {
                    CurrentDataBaseInfo = configInfo.DataBaseInfo;
                    var sourceDataBaseInfo = CurrentDataBaseInfo.DataBaseInfos.FirstOrDefault(x => x.DataBaseType == CurrentDataBaseInfo.SourceType && x.Ip == CurrentDataBaseInfo.SourceIp);                   
                    txbSourceUserName.Text = sourceDataBaseInfo.UserName;
                    txbSourcePassword.Text = sourceDataBaseInfo.Password;
                    sourcePort.Text = sourceDataBaseInfo.Port;
                    dataBaseTypeSource.SelectedIndex = Convert.ToInt32(CurrentDataBaseInfo?.SourceType);
                    var targetDataBaseInfo = CurrentDataBaseInfo.DataBaseInfos.FirstOrDefault(x => x.DataBaseType == CurrentDataBaseInfo.TargetType && x.Ip == CurrentDataBaseInfo.TargetIp);                    
                    txbTargetUserName.Text = targetDataBaseInfo.UserName;
                    txbTargetPassword.Text = targetDataBaseInfo.Password;
                    targetPort.Text = targetDataBaseInfo.Port;
                    dataBaseTypeTarget.SelectedIndex = Convert.ToInt32(CurrentDataBaseInfo?.TargetType);
                    //cmbSourceIP.DataSource
                    sourceDataBases = CurrentDataBaseInfo.DataBaseInfos.Where(x => x.DataBaseType == dataBaseTypeSource.SelectedIndex.ToString()).ToList();
                    targetDataBases = CurrentDataBaseInfo.DataBaseInfos.Where(x => x.DataBaseType == dataBaseTypeTarget.SelectedIndex.ToString()).ToList();
                    cmbSourceIP.DataSource = sourceDataBases.Select(x => x.Ip).ToList();
                    cmbTargetIP.DataSource = targetDataBases.Select(x => x.Ip).ToList();
                    cmbSourceIP.Text = CurrentDataBaseInfo?.SourceIp;
                    cmbTargetIP.Text = CurrentDataBaseInfo?.TargetIp;
                    sqlServerDataBases = CurrentDataBaseInfo.DataBaseInfos.Where(x => x.DataBaseType == "0").ToList();
                    mySqlDataBases = CurrentDataBaseInfo.DataBaseInfos.Where(x => x.DataBaseType == "1").ToList();
                }
                //string path = "C:\\表述工具数据库比对配置文件.ldt";
                //if (File.Exists(path))
                //{
                //    string pz = File.ReadAllText(path, Encoding.UTF8);
                //    if (!string.IsNullOrWhiteSpace(pz))
                //    {
                //        if (pz.Contains(","))
                //        {
                //            pz = string.Empty;
                //        }
                //        else
                //        {
                //            CurrentDataBaseInfo = JsonConvert.DeserializeObject<DataBaseSave>(pz);
                //            var sourceDataBaseInfo = CurrentDataBaseInfo.DataBaseInfos.FirstOrDefault(x => x.DataBaseType == CurrentDataBaseInfo.SourceType && x.Ip == CurrentDataBaseInfo.SourceIp);
                //            cmbSourceIP.Text = CurrentDataBaseInfo?.SourceIp;
                //            txbSourceUserName.Text = sourceDataBaseInfo.UserName;
                //            txbSourcePassword.Text = sourceDataBaseInfo.Password;
                //            sourcePort.Text = sourceDataBaseInfo.Port;
                //            dataBaseTypeSource.SelectedIndex = Convert.ToInt32(CurrentDataBaseInfo?.SourceType);
                //            var targetDataBaseInfo = CurrentDataBaseInfo.DataBaseInfos.FirstOrDefault(x => x.DataBaseType == CurrentDataBaseInfo.TargetType && x.Ip == CurrentDataBaseInfo.TargetIp);
                //            cmbTargetIP.Text = CurrentDataBaseInfo?.TargetIp;
                //            txbTargetUserName.Text = targetDataBaseInfo.UserName;
                //            txbTargetPassword.Text = targetDataBaseInfo.Password;
                //            targetPort.Text = targetDataBaseInfo.Port;
                //            dataBaseTypeTarget.SelectedIndex = Convert.ToInt32(CurrentDataBaseInfo?.TargetType);
                //        }
                //    }
                //}
                else
                {
                    //来源默认sqlserver
                    dataBaseTypeSource.SelectedIndex = 0;
                    //目标默认mysql
                    dataBaseTypeTarget.SelectedIndex = 1;
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("界面加载数据出错：" + ex.Message.ToString());
            }
        }

        /// <summary>
        /// 来源数据库点击事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void txbSourceContent_Click(object sender, EventArgs e)
        {
            if (!string.IsNullOrWhiteSpace(cmbSourceIP.Text.Trim()) && PublicMethod.IsTextBoxRight(txbSourceUserName) && PublicMethod.IsTextBoxRight(txbSourcePassword) && PublicMethod.IsTextBoxRight(sourcePort))
            {
                if (!CheckConnect(cmbSourceIP, txbSourceUserName, txbSourcePassword, sourcePort, dataBaseTypeSource.SelectedIndex))
                {
                    MessageBox.Show("数据库链接失败，请确保数据库信息填写正确！");
                }
                else
                {
                    MessageBox.Show("连接成功！");
                }
            }
        }

        /// <summary>
        /// 检查数据库的链接状态
        /// </summary>
        /// <param name="ip">IP地址文本框</param>
        /// <param name="userName">用户名文本框</param>
        /// <param name="passWord">密码文本框</param>
        /// <param name="port">端口文本框</param>
        /// <param name="type">类型 0sqlserver数据库 1MySQL数据库</param>
        /// <returns>连接成功还是失败</returns>
        private bool CheckConnect(ComboBox ip, TextBox userName, TextBox passWord, TextBox port, int type)
        {
            switch (type)
            {
                case 0:
                    if (!OpenConnectTest(ip.Text, userName.Text, passWord.Text, port.Text, 0))
                    {
                        return false;
                    }
                    break;
                case 1:
                    if (!OpenConnectTest(ip.Text, userName.Text, passWord.Text, port.Text, 1))
                    {
                        return false;
                    }
                    break;
            }
            return true;
        }

        /// <summary>
        /// 数据库链接测试
        /// </summary>
        /// <param name="server">IP地址</param>
        /// <param name="username">用户名</param>
        /// <param name="password">密码</param>
        /// <param name="type">数据库类型 默认0 sqlserver 1mysql</param>
        /// <returns>连接成功还是失败</returns>
        public bool OpenConnectTest(string server, string username, string password, string port, int type)
        {
            string connectionString;
            try
            {
                if (type == 0)
                {
                    connectionString = $" Server={server};Database=master;User ID={username};Password={password}; ";
                    SqlConnection conn = new SqlConnection(connectionString);
                    conn.Open();
                    conn.Close();
                }
                else
                {
                    connectionString = $" Server={server};Port={port};Database=ldtcommonmanage;Uid={username};Pwd={password}; ";
                    MySqlConnection conn = new MySqlConnection(connectionString);
                    conn.Open();
                    conn.Close();
                }
                return true;
            }
            catch (Exception)
            {
                return false;
                //throw new Exception("数据库连接出错：" + ex.Message);                
            }
        }

        /// <summary>
        /// 目标数据库点击事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void txbTargetConnect_Click(object sender, EventArgs e)
        {
            if (!string.IsNullOrWhiteSpace(cmbTargetIP.Text.Trim()) && PublicMethod.IsTextBoxRight(txbTargetUserName) && PublicMethod.IsTextBoxRight(txbTargetPassword) && PublicMethod.IsTextBoxRight(targetPort))
            {
                if (!CheckConnect(cmbTargetIP, txbTargetUserName, txbTargetPassword, targetPort, dataBaseTypeTarget.SelectedIndex))
                {
                    MessageBox.Show("数据库链接失败，请确保数据库信息填写正确！");
                }
                else
                {
                    MessageBox.Show("连接成功！");
                }
            }
        }

        /// <summary>
        /// 根据类型和IP地址、用户名、密码、端口返回IFreeSql
        /// </summary>
        /// <param name="ip">ip地址</param>
        /// <param name="userName">用户名</param>
        /// <param name="passWord">密码</param>
        /// <param name="port">端口</param>
        /// <param name="type">数据库类型 默认0 sqlserver 1mysql</param>
        /// <returns>IFreeSql对象</returns>
        private IFreeSql GetFreeSql(ComboBox ip, TextBox userName, TextBox passWord, TextBox port, int type)
        {
            if (type == 0)
            {
                return new Lazy<IFreeSql>(() => new FreeSql.FreeSqlBuilder()
           .UseMonitorCommand(cmd =>
           Console.WriteLine($"sql:{cmd.CommandText}")
           )
           .UseNoneCommandParameter(true)
           .UseConnectionString(FreeSql.DataType.SqlServer, $"Server={ip.Text.Trim()};Database='LdtCommonManage';User ID={userName.Text.Trim()};Password={passWord.Text.Trim()};")
           .Build()
            ).Value;
            }
            else
            {
                return new Lazy<IFreeSql>(() => new FreeSql.FreeSqlBuilder()
            .UseMonitorCommand(cmd =>
            Console.WriteLine($"sql:{cmd.CommandText}")
            )
            .UseNoneCommandParameter(true)
            .UseConnectionString(FreeSql.DataType.MySql, $"Server={ip.Text.Trim()};Database='ldtcommonmanage';Port={port.Text.Trim()};Uid={userName.Text.Trim()};Pwd={passWord.Text.Trim()};")
            .Build()
            ).Value;
            }
        }

        /// <summary>
        /// 正则数据比对
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnCompare_Click(object sender, EventArgs e)
        {
            if (PublicMethod.IsTextBoxRight(txbCode) && CheckConnect(cmbSourceIP, txbSourceUserName, txbSourcePassword, sourcePort, dataBaseTypeSource.SelectedIndex)
                && CheckConnect(cmbTargetIP, txbTargetUserName, txbTargetPassword, targetPort, dataBaseTypeTarget.SelectedIndex))
            {
                if (CurrentDataBaseInfo == null || !CurrentDataBaseInfo.DataBaseInfos.Any())
                {
                    CurrentDataBaseInfo.SourceIp = cmbSourceIP.Text.Trim();
                    CurrentDataBaseInfo.SourceType = dataBaseTypeSource.SelectedIndex.ToString();
                }
                if (configInfo.DataBaseInfo == null)
                {
                    configInfo.DataBaseInfo = new DataBaseSave() { };
                }
                configInfo.DataBaseInfo.SourceIp = cmbSourceIP.Text.Trim();
                configInfo.DataBaseInfo.SourceType = dataBaseTypeSource.SelectedIndex.ToString();
                configInfo.DataBaseInfo.TargetIp = cmbTargetIP.Text.Trim();
                configInfo.DataBaseInfo.TargetType = dataBaseTypeTarget.SelectedIndex.ToString();
                if (configInfo.DataBaseInfo.DataBaseInfos == null)
                {
                    configInfo.DataBaseInfo.DataBaseInfos = new List<DataBaseInfo>();
                }

                if (configInfo.DataBaseInfo.DataBaseInfos.Any(x => x.Ip == cmbSourceIP.Text.Trim() && x.DataBaseType == dataBaseTypeSource.SelectedIndex.ToString()))
                {
                    var info = configInfo.DataBaseInfo.DataBaseInfos.FirstOrDefault(x => x.Ip == cmbSourceIP.Text.Trim() && x.DataBaseType == dataBaseTypeSource.SelectedIndex.ToString());
                    info.UserName = txbSourceUserName.Text.Trim();
                    info.Password = txbSourcePassword.Text.Trim();
                    info.Port = sourcePort.Text.Trim();
                }
                else
                {
                    configInfo.DataBaseInfo.DataBaseInfos.Add(new DataBaseInfo()
                    {
                        Ip = cmbSourceIP.Text.Trim(),
                        DataBaseType = dataBaseTypeSource.SelectedIndex.ToString(),
                        UserName = txbSourceUserName.Text.Trim(),
                        Password = txbSourcePassword.Text.Trim(),
                        Port = sourcePort.Text.Trim()
                    }); ;
                }

                var i1 = configInfo.DataBaseInfo.DataBaseInfos;
                if (configInfo.DataBaseInfo.DataBaseInfos.Any(x => x.Ip == cmbTargetIP.Text.Trim() && x.DataBaseType == dataBaseTypeTarget.SelectedIndex.ToString()))
                {
                    var info = configInfo.DataBaseInfo.DataBaseInfos.FirstOrDefault(x => x.Ip == cmbTargetIP.Text.Trim() && x.DataBaseType == dataBaseTypeTarget.SelectedIndex.ToString());
                    info.UserName = txbTargetUserName.Text.Trim();
                    info.Password = txbTargetPassword.Text.Trim();
                    info.Port = targetPort.Text.Trim();
                }
                else
                {
                    configInfo.DataBaseInfo.DataBaseInfos.Add(new DataBaseInfo()
                    {
                        Ip = cmbTargetIP.Text.Trim(),
                        DataBaseType = dataBaseTypeTarget.SelectedIndex.ToString(),
                        UserName = txbTargetUserName.Text.Trim(),
                        Password = txbTargetPassword.Text.Trim(),
                        Port = targetPort.Text.Trim()
                    }); ;
                }

                var info1 = JsonConvert.SerializeObject(configInfo);
                File.WriteAllText(System.Configuration.ConfigurationManager.AppSettings["ConfigPath"], info1);




                //if (!configInfo.LoginInfo.UserNames.Contains(userName))
                //{
                //    configInfo.LoginInfo.UserNames.Add(userName);
                    
                //}

                //StringBuilder sb = new StringBuilder();
                //sb.AppendLine(string.Join(",", txbSourceIP.Text.Trim(), txbSourceUserName.Text.Trim(), txbSourcePassword.Text.Trim(), sourcePort.Text.Trim(), dataBaseTypeSource.SelectedIndex));
                //sb.AppendLine(string.Join(",", txbTargetIP.Text.Trim(), txbTargetUserName.Text.Trim(), txbTargetPassword.Text.Trim(), targetPort.Text.Trim(), dataBaseTypeTarget.SelectedIndex));
                //File.AppendAllText("C:\\表述工具数据库比对配置文件.ldt", sb.ToString(), Encoding.UTF8);

                IFreeSql CommonManageSource = GetFreeSql(cmbSourceIP, txbSourceUserName, txbSourcePassword, sourcePort, dataBaseTypeSource.SelectedIndex);
                IFreeSql CommonManageTarget = GetFreeSql(cmbTargetIP, txbTargetUserName, txbTargetPassword, targetPort, dataBaseTypeTarget.SelectedIndex);
                List<RegexInfo> sourceList;
                List<RegexInfo> targetList;
                if (cmbRegexType.SelectedIndex == 1)
                {
                    sourceList = CommonManageSource.Select<RuleInfoUnit, Riu_RuleRelation, Riu_Regexs>().InnerJoin((a, b, c) => a.RIU_ID == b.RIU_ID).InnerJoin((a, b, c) => b.RR_RelationTable_ID == c.ER_ID).Where((a, b, c) => a.RIU_Code == txbCode.Text.Trim()).OrderBy((a, b, c) => b.RR_Index)?.ToList((a, b, c) => new RegexInfo { ER_ID = c.ER_ID, ER_RegexText = c.ER_RegexText });
                    targetList = CommonManageTarget.Select<RuleInfoUnit, Riu_RuleRelation, Riu_Regexs>().InnerJoin((a, b, c) => a.RIU_ID == b.RIU_ID).InnerJoin((a, b, c) => b.RR_RelationTable_ID == c.ER_ID).Where((a, b, c) => a.RIU_Code == txbCode.Text.Trim()).OrderBy((a, b, c) => b.RR_Index)?.ToList((a, b, c) => new RegexInfo { ER_ID = c.ER_ID, ER_RegexText = c.ER_RegexText });
                }
                else
                {
                    sourceList = CommonManageSource.Select<Reg_InfoUnit, Reg_InfoRegexRelation, Reg_Regexs>().InnerJoin((a, b, c) => a.EI_ID == b.EI_ID).InnerJoin((a, b, c) => b.ER_ID == c.ER_ID).Where((a, b, c) => a.EI_ID == txbCode.Text.Trim()).OrderBy((a, b, c) => b.ERR_ShowIndex)?.ToList((a, b, c) => new RegexInfo { ER_ID = c.ER_ID, ER_RegexText = c.ER_RegexText });
                    targetList = CommonManageTarget.Select<Reg_InfoUnit, Reg_InfoRegexRelation, Reg_Regexs>().InnerJoin((a, b, c) => a.EI_ID == b.EI_ID).InnerJoin((a, b, c) => b.ER_ID == c.ER_ID).Where((a, b, c) => a.EI_ID == txbCode.Text.Trim()).OrderBy((a, b, c) => b.ERR_ShowIndex)?.ToList((a, b, c) => new RegexInfo { ER_ID = c.ER_ID, ER_RegexText = c.ER_RegexText });
                }

                if (sourceList.Count > 0)
                {
                    dgvSource.DataSource = sourceList;
                }
                if (targetList.Count > 0)
                {
                    dgvTarget.DataSource = targetList;
                }
                for (int i = 0; i < dgvSource.RowCount; i++)
                {
                    if (dgvTarget.Rows.Count > i && !dgvTarget.Rows[i].Cells[1].Value.Equals(dgvSource.Rows[i].Cells[1].Value))
                    {
                        dgvSource.Rows[i].DefaultCellStyle.ForeColor = Color.Red;
                    }
                }

            }
            else
            {
                MessageBox.Show("数据库链接失败，请先进行测试连接！");
            }
        }

        /// <summary>
        /// 来源IP地址切换事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void cmbSourceIP_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (sourceDataBases.Any())
            {
                var info = sourceDataBases.FirstOrDefault(x => x.Ip == cmbSourceIP.Text.Trim());
                if (info != null)
                {
                    txbSourceUserName.Text = info.UserName;
                    txbSourcePassword.Text = info.Password;
                    sourcePort.Text = info.Port;
                }
            }
        }

        /// <summary>
        /// 目标IP地址切换事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void cmbTargetIP_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (targetDataBases.Any())
            {
                var info = targetDataBases.FirstOrDefault(x => x.Ip == cmbTargetIP.Text.Trim());
                if (info != null)
                {
                    txbTargetUserName.Text = info.UserName;
                    txbTargetPassword.Text = info.Password;
                    targetPort.Text = info.Port;
                }
            }
        }

        /// <summary>
        /// 来源类型切换事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void dataBaseTypeSource_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (sqlServerDataBases.Any() && mySqlDataBases.Any())
            {
                switch (dataBaseTypeSource.SelectedIndex)
                {
                    case 0:
                        cmbSourceIP.DataSource = sqlServerDataBases?.Select(x => x.Ip).ToList();
                        cmbSourceIP.Text = ((List<string>)cmbSourceIP.DataSource)[0];
                        var info = sqlServerDataBases.FirstOrDefault(x => x.Ip == cmbSourceIP.Text.Trim());
                        if (info != null)
                        {
                            txbSourceUserName.Text = info.UserName;
                            txbSourcePassword.Text = info.Password;
                            sourcePort.Text = info.Port;
                        }
                        break;
                    case 1:
                        cmbSourceIP.DataSource = mySqlDataBases?.Select(x => x.Ip).ToList();
                        cmbSourceIP.Text = ((List<string>)cmbSourceIP.DataSource)[0];
                        var info1 = mySqlDataBases.FirstOrDefault(x => x.Ip == cmbSourceIP.Text.Trim());
                        if (info1 != null)
                        {
                            txbSourceUserName.Text = info1.UserName;
                            txbSourcePassword.Text = info1.Password;
                            sourcePort.Text = info1.Port;
                        }
                        break;
                }
            }           
        }

        /// <summary>d
        /// 目标类型切换事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void dataBaseTypeTarget_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (sqlServerDataBases.Any() && mySqlDataBases.Any())
            {
                switch (dataBaseTypeTarget.SelectedIndex)
                {
                    case 0:
                        cmbTargetIP.DataSource = sqlServerDataBases?.Select(x => x.Ip).ToList();
                        cmbTargetIP.Text = ((List<string>)cmbTargetIP.DataSource)[0];
                        var info = sqlServerDataBases.FirstOrDefault(x => x.Ip == cmbTargetIP.Text.Trim());
                        if (info != null)
                        {
                            txbTargetUserName.Text = info.UserName;
                            txbTargetPassword.Text = info.Password;
                            targetPort.Text = info.Port;
                        }
                        break;
                    case 1:
                        cmbTargetIP.DataSource = mySqlDataBases?.Select(x => x.Ip).ToList();
                        cmbTargetIP.Text = ((List<string>)cmbTargetIP.DataSource)[0];
                        var info1 = mySqlDataBases.FirstOrDefault(x => x.Ip == cmbTargetIP.Text.Trim());
                        if (info1 != null)
                        {
                            txbTargetUserName.Text = info1.UserName;
                            txbTargetPassword.Text = info1.Password;
                            targetPort.Text = info1.Port;
                        }
                        break;
                }
                cmbTargetIP.Text = ((List<string>)cmbTargetIP.DataSource)[0];

            }
        }
    }

    /// <summary>
    /// 信息单元类
    /// </summary>
    public class RegexInfo
    {
        /// <summary>
        /// 主键ID
        /// </summary>
        public string ER_ID { get; set; }

        /// <summary>
        /// 正则内容
        /// </summary>
        public string ER_RegexText { get; set; }
    }
    //sb.AppendLine(string.Join(",", txbSourceIP.Text.Trim(), txbSourceUserName.Text.Trim(), txbSourcePassword.Text.Trim(), sourcePort.Text.Trim(), dataBaseTypeSource.SelectedIndex));


}
